package cn.vire.electric.simulation.config.aspect;

import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;

@Aspect
@Component
public class LogAspect {
    private static Logger logger = LoggerFactory.getLogger(LogAspect.class);

    /**
     * web在执行方法前后，增加日志
     *
     * @param jp 切点
     * @return
     * @throws Throwable
     */
    @Around("execution(* cn.vire.electric.simulation.controller.*Controller.*(..))")
    public Object webLogAround(ProceedingJoinPoint jp) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String uri = request.getRequestURI().toString();
        String token = request.getHeader("token");
        String targetName = jp.getSignature().toString();
        logger.info(targetName + " start.");
        try {
            HashMap<String, Object> argMap = null;
            StringBuilder sb = new StringBuilder("[");
            Object[] args = jp.getArgs();
            if (args != null && args.length > 0) {
                argMap = new HashMap<>();
                for (int i = 0; i < args.length; i++) {
                    Object arg = args[i];
                    if (arg != null) {
                        Class<?> argClass = arg.getClass();
                        boolean skip = argClass.isInterface() || arg instanceof ServletRequest || arg instanceof ServletResponse
                                || argClass.getName().startsWith("javax.servlet") || argClass.getName().startsWith("org.springframework");
                        if (!skip) {//过滤request,response等参数
                            argMap.put(argClass.getSimpleName(), arg);
                        }
                    }
                }
            }
            logger.info("URI:{}, METHOD:{}, IP:{}, TOKEN:{}, ARGS:{}", uri, request.getMethod(), request.getRemoteAddr(), token, JSONObject.toJSONString(argMap));
        } catch (Exception e) {
            logger.warn(targetName + " 打印请求信息报错");
        }

        Long start = System.currentTimeMillis();
        Object rvt = jp.proceed();
        Long runingtime = System.currentTimeMillis() - start;

        try {
            String logResult = JSONObject.toJSONString(rvt);
            if (logResult.length() > 1024) {
                logResult = logResult.substring(0, 1024);
            }
            logger.info("URI:{},api running time: {}ms", uri, runingtime);
            logger.info("URI:{},logResult return:{} ...", uri, logResult);
            logger.info(targetName + " end.");
        } catch (Throwable e) {
            logger.warn(targetName + " 打印请求结果报错");
        }
        return rvt;
    }

}
